/**   
* @Title: DynamicDataSourceAnnotationInterceptor.java
* @Package org.xaoyaoyao.cloud.dynamic.aop
* @Description: TODO
* @author xaoyaoyao
* @date Jul 3, 2019 4:11:28 PM
* @version V1.0   
*/
package org.xaoyaoyao.cloud.dynamic.aop;

import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;

import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
import org.springframework.core.annotation.AnnotationUtils;
import org.xaoyaoyao.cloud.dynamic.annotation.DynamicDataSource;
import org.xaoyaoyao.cloud.dynamic.source.DynamicDataSourceContextHolder;

import lombok.extern.slf4j.Slf4j;

/**
 * @ClassName: DynamicDataSourceAnnotationInterceptor
 * @Description: TODO
 * @author xaoyaoyao
 * @date Jul 3, 2019 4:11:28 PM
 * 
 */
@Slf4j
public class DynamicDataSourceAnnotationInterceptor implements MethodInterceptor {

	/**
	 * 缓存方法注解值
	 */
	private static final Map<Method, String> METHOD_CACHE = new HashMap<>();

	@Override
	public Object invoke(MethodInvocation invocation) throws Throwable {
		try {
			String datasource = determineDatasource(invocation);
			if (!DynamicDataSourceContextHolder.containsDataSource(datasource)) {
				if (log.isInfoEnabled()) {
					log.info(">>>>>>>> 数据源[{}]不存在，使用默认数据源 >", datasource);
				}
			}
			DynamicDataSourceContextHolder.setDataSourceRouterKey(datasource);
			return invocation.proceed();
		} finally {
			DynamicDataSourceContextHolder.removeDataSourceRouterKey();
		}
	}

	private String determineDatasource(MethodInvocation invocation) {
		Method method = invocation.getMethod();
		if (METHOD_CACHE.containsKey(method)) {
			return METHOD_CACHE.get(method);
		} else {
			DynamicDataSource ds = method.isAnnotationPresent(DynamicDataSource.class) ? method.getAnnotation(DynamicDataSource.class)
					: AnnotationUtils.findAnnotation(method.getDeclaringClass(), DynamicDataSource.class);
			METHOD_CACHE.put(method, ds.value());
			return ds.value();
		}
	}
}
